﻿using Microsoft.AspNetCore.Mvc.ActionConstraints;
using Microsoft.AspNetCore.Mvc.ApplicationModels;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Volo.Abp.AspNetCore.Mvc.Conventions;
using Volo.Abp.AspNetCore.Mvc;
using Volo.Abp.AspNetCore;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Reflection;
using Volo.Abp;

namespace Framework.AspNetCore.Mvc
{
	[Dependency(ServiceLifetime.Transient, ReplaceServices = true)]
	[ExposeServices(typeof(IAbpServiceConvention))]
	public class MyServiceConvention : AbpServiceConvention
	{
		public MyServiceConvention(IOptions<AbpAspNetCoreMvcOptions> options, IConventionalRouteBuilder conventionalRouteBuilder) : base(options, conventionalRouteBuilder)
		{
		}

		protected override void ConfigureSelector(string rootPath, string controllerName, ActionModel action, ConventionalControllerSetting? configuration)
		{
			RemoveEmptySelectors(action.Selectors);     // 删除asp.net core 框架为动态 Web API 控制器生成的空白信息

			// 判断是否有RemoteServiceAttribute 特性(忽略生成api资源),并为false(为false才是禁用，默认是true，也就是不禁用)则后续不进行处理
			var remoteServiceAtt = ReflectionHelper.GetSingleAttributeOrDefault<RemoteServiceAttribute>(action.ActionMethod);
			if (remoteServiceAtt != null && !remoteServiceAtt.IsEnabledFor(action.ActionMethod))
			{
				return;
			}

			if (!action.Selectors.Any())
			{   // 
				AddAbpServiceSelector(rootPath, controllerName, action, configuration);
			}
			else
			{
				NormalizeSelectorRoutes(rootPath, controllerName, action, configuration);
			}
		}


		protected override void AddAbpServiceSelector(string rootPath, string controllerName, ActionModel action, ConventionalControllerSetting? configuration)
		{
			base.AddAbpServiceSelector(rootPath, controllerName, action, configuration);
		}

		protected override void NormalizeSelectorRoutes(string rootPath, string controllerName, ActionModel action, ConventionalControllerSetting? configuration)
		{
			foreach (var selector in action.Selectors)
			{
				// 是否有自定义HTTP Method的方法
				var httpMethod = selector.ActionConstraints
					.OfType<HttpMethodActionConstraint>()
					.FirstOrDefault()?
					.HttpMethods?
					.FirstOrDefault();

				if (httpMethod == null) // 没有自定义HTTP Method的方法
				{
					httpMethod = SelectHttpMethod(action, configuration);
				}

				if (selector.AttributeRouteModel == null)
				{   // 没有自定义路由
					selector.AttributeRouteModel = CreateAbpServiceAttributeRouteModel(rootPath, controllerName, action, httpMethod, configuration);
				}
				else
				{   // 自定义路由
					var template = selector.AttributeRouteModel.Template;
					if (!template.StartsWith("/"))
					{
						var route = $"{AbpAspNetCoreConsts.DefaultApiPrefix}/{rootPath}/{template}";
						selector.AttributeRouteModel.Template = route;

					}
				}

				if (!selector.ActionConstraints.OfType<HttpMethodActionConstraint>().Any())
				{
					selector.ActionConstraints.Add(new HttpMethodActionConstraint(new[] { httpMethod }));
				}
			}
		}
	}
}
